<template>
  <el-dialog
    v-model="visible"
    title="发布动态"
    width="50%"
    center
    top="10vh"
    :close-on-click-modal="false"
    @closed="close"
  >
    <el-form
      ref="formRef"
      :model="dynamicData"
      :rules="rules"
      label-width="100px"
      style="margin-top: 20px;max-width: 800px;"
    >
      <el-form-item label="发布类型" prop="fileType">
        <el-radio-group v-model="dynamicData.fileType">
          <el-radio :label="1">图文动态</el-radio>
          <el-radio :label="2">视频动态</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="分类" prop="recommendType">
        <el-select v-model="dynamicData.recommendType">
          <el-option
            v-for="item in classifyList"
            :key="item.recommendTypeId"
            :label="item.name"
            :value="item.recommendTypeId"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="动态文案" prop="remark">
        <el-input
          v-model="dynamicData.remark"
          type="textarea"
          maxlength="2000"
        />
      </el-form-item>
      <el-form-item label="动态图" v-if="dynamicData.fileType===1" prop="fileUrl" ref="imgRef">
          <!-- :on-remove="handleRemove" -->

        <el-upload
          list-type="picture-card"
          accept="'.png, .jpeg, .jpg, .webp'"
          :on-preview="handlePictureCardPreview"
          :headers="uploadSetting.headers"
          :data="uploadSetting.data"
          :file-list="dynamicData.fileUrl"
          :limit="9"
          :on-success="handleImageSuccess"
          :action="uploadUrl"
          :on-remove="handleRemove"
          :before-upload="beforeAvatarUpload"
          :class="dynamicData.fileUrl.length === 9?'hide_box':''"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <p>支持上传5M以内的图片</p>
      </el-form-item>
      <el-form-item label="动态视频" v-else prop="videoUrl" ref="videoRef">
        <el-upload
          ref="uploadRef"
          list-type="picture-card"
          :headers="uploadSetting.headers"
          :action="uploadUrl"
          :file-list="dynamicData.videoUrl"
          :limit="1"
          accept=".mp4, .webm"
          :on-success="handleImageSuccess"
          :before-upload="beforeAvatarUpload"
          :class="dynamicData.videoUrl.length === 1?'hide_box':''"
        >
          <el-icon><Plus /></el-icon>
          <template #file="{ file }">
            <div style="width: 100%;">
              <video controls="controls" loop="loop" width="100%" height="100%">
                <source :src="dynamicData.videoUrl[0].url" type="video/mp4" />
              </video>
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <el-icon><Delete /></el-icon>
                </span>
              </span>
            </div>
          </template>
        </el-upload>
        <p>最多支持上传15分钟长度的视频</p>
      </el-form-item>
      <el-form-item label="视频封面" v-if="dynamicData.fileType===2" prop="cover" ref="coverRef">
        <el-upload
          list-type="picture-card"
          accept="'.png, .jpeg, .jpg, .webp'"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleCoverRemove"
          :headers="uploadSetting.headers"
          :data="uploadSetting.data"
          :file-list="dynamicData.cover"
          :limit="1"
          :on-success="handleCoverSuccess"
          :action="uploadUrl"
          :before-upload="beforeCoverUpload"
          :class="dynamicData.cover.length === 1?'hide_box':''"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <p>支持上传5M以内的图片</p>
      </el-form-item>
      <el-form-item label="关联商品">
        <div>
          <el-button plain type="primary" @click="addProduct">请选择</el-button>
          <el-table
            :data="products"
            border
            :header-cell-style="{ background: '#EEF3FF', color: '#333333' }"
            tooltip-effect="dark"
            style="width: 100%;margin-top: 20px;"
            max-height="400"
          >
            <el-table-column
              prop="productId"
              label="商品id"
              show-overflow-tooltip
            />
            <el-table-column label="商品图片" width="220" align="center">
              <template #default="scope">
                <img
                  height="80"
                  width="80"
                  :src="scope.row.productImage"
                  alt
                  srcset
                />
              </template>
            </el-table-column>
            <el-table-column
              prop="productName"
              label="商品名称"
              align="center"
            />
            <el-table-column
              prop="section"
              label="售价区间"
              show-overflow-tooltip
              width="140"
            />
            <el-table-column label="操作">
              <template #default="scope">
                <el-button type="danger" link @click="delProduct(scope)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-form-item>
      <el-form-item style="margin-top: 50px;">
        <el-button plain @click="close">取消</el-button>
        <el-button plain type="primary" @click="publish(formRef)">发布</el-button>
      </el-form-item>
    </el-form>
    <!-- 图片预览 -->
    <el-dialog
      v-model="imgVisible.image"
      :append-to-body="true"
      class="check-image-dialog"
      title="查看图片"
      center="center"
    >
      <img :src="detailImage" alt class="preview-img"/>
    </el-dialog>
    <!-- 商品列表 -->
    <el-dialog
      v-model="isShowManualAdd"
      title="手动添加商品"
      width="65%"
      top="50px"
      center
      class="group-dialog"
      :close-on-click-modal="false"
      :modal-append-to-body="false"
      :modal="false"
    >
      <!-- 搜索 -->
      <div class="formSearch" style="margin-top: 20px;">
        <el-form :inline="true" :model="formInline">
          <el-form-item label="商品id">
            <el-input
              v-model="formInline.productId"
              maxlength="20"
              placeholder="搜索商品ID"
            />
          </el-form-item>
          <el-form-item label="商品名称">
            <el-input
              v-model="formInline.search"
              maxlength="20"
              placeholder="搜索商品名称"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" plain @click="getAll">查询</el-button>
            <el-button plain @click="clearData">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="tableBox">
        <el-table
          :data="shopListData"
          ref="multipleTableRef"
          border
          :header-cell-style="{ background: '#EEF3FF', color: '#333333' }"
          tooltip-effect="dark"
          style="width: 100%"
          :row-key="row=>row.productId"
          max-height="550"
          @select="handleSelect"
          @select-all="handleSelectAll"
        >
          <el-table-column
              type="selection"
              :reserve-selection="true"
              width="55"
          />
          <el-table-column
            prop="productId"
            label="商品id"
            show-overflow-tooltip
          />
          <el-table-column label="商品图片" width="220" align="center">
            <template #default="scope">
              <img height="80" width="80" :src="scope.row.productImage" alt srcset />
            </template>
          </el-table-column>
          <el-table-column
            prop="productName"
            label="商品名称"
            width="220"
            align="center"
          />
          <el-table-column
            prop="section"
            label="售价区间"
            show-overflow-tooltip
            width="140"
          />
          <el-table-column
            prop="stockNumber"
            label="库存（件）"
            align="center"
            show-overflow-tooltip
          />
          <el-table-column prop="volume" label="销量" show-overflow-tooltip />
          <el-table-column prop="volume" label="上架状态" show-overflow-tooltip width="100">
            <template #default="scope">
              <span v-if="scope.row.shelveState == 0">未上架</span>
              <span v-if="scope.row.shelveState == 1">已上架</span>
              <span v-if="scope.row.shelveState == 2">待审核</span>
              <span v-if="scope.row.shelveState == 3">审核失败</span>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          :current-page="formInline.page"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="formInline.pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="shopTotal"
          style="margin: 30px 0 0 0;"
          @size-change="val=> {handlePageChange(val, 'pageSize')}"
          @current-change="val=> {handlePageChange(val, 'page')}"
        />
      </div>
      <template #footer>
        <el-button type="primary" @click="saveIdList">确 定</el-button>
        <el-button @click="closeSelect">取 消</el-button>
      </template>
    </el-dialog>

  </el-dialog>
</template>

<script setup>
import {ref, shallowRef, reactive, nextTick} from "vue";
import { uploadUrl } from '@/utils/request';
import { getToken } from '@/utils/auth';
import {
  getAllClassify,
  contentInfo,
  contentEdit,
  contentAdd
  } from '@/api/content';
import { getClassifyGetAll} from '@/api/commodity';

const emits = defineEmits(['reload'])
let visible = ref(false);
let imgVisible = reactive({
  image: false,
});
let detailImage = shallowRef('');
let uploadSetting = reactive({
  headers: {
    'Authorization-business': getToken(),
    tenant: 'MDAwMA=='
  },
  data: {
    folderId: 1,
  }
});
const classifyList = ref([]);
const isShowManualAdd = ref(false); // 选择商品弹框
const defaultProductParam = {
  page: 1, // 当前页
  pageSize: 10, // 每页记录数
  search: '', // 商品名称
  productId: "" // 商品ID
};
const formInline = ref({...defaultProductParam});
const shopListData = ref([]);
const selectShopList = ref([]);
const shopTotal = ref(1);
const multipleTableRef = ref();
const coverRef = ref(null);
const imgRef = ref(null);
const videoRef = ref(null);

const products = ref([]) // 确定已选商品

function DynamicData() {
  this.fileType = 1 // 发布类型 1-图文动态 2-视频动态
  this.recommendType = '' // 分类
  this.remark = '' // 文案
  this.fileUrl = [] // 图片
  this.videoUrl = [] // 视频
  this.cover = [] // 视频封面
  this.productIds = [] // 关联商品
}
let dynamicData = ref(new DynamicData());
const formRef = ref(null)
const rules = ref({
  fileType: [
    { required: true, message: '请选择发布类型', trigger: 'change' },
  ],
  recommendType: [
    { required: true, message: '请选择分类', trigger: 'change' },
  ],
  remark: [
    { required: true, message: '请输入文案', trigger: 'blur' },
  ],
  fileUrl: [
    { required: true, message: '请上传图片', trigger: 'blur' },
  ],
  cover: [
    { required: true, message: '请上传视频封面', trigger: 'change' },
  ],
  videoUrl: [
    { required: true, message: '请上传视频', trigger: 'change' },
  ]
});

// 打开分组弹窗
const open = async(item) => {
  const {recommendId=''} = item
  if(recommendId) {
    dynamicData.value.recommendId = recommendId;
    const {code:rCode, data:rData} = await contentInfo({recommendId});
    if(rCode==='') {
      products.value = rData.products;
      Object.keys(dynamicData.value).forEach(key => {
        if(!["fileUrl", "videoUrl", 'cover'].includes(key)) dynamicData.value[key] = rData[key];
        if(key==='productIds') {
          dynamicData.value.productIds = rData.products.map(it=>it.productId);
        }
        if(key==="cover"&&rData[key]) {
          dynamicData.value[key] = [{
            imgPath: rData[key],
            url: rData[key]
          }]
        }
      })
      // 图文、视频字段回显
      const field = rData.fileType===1?"fileUrl":"videoUrl";
      dynamicData.value[field] = rData.fileUrl?rData.fileUrl.split(',').map(it => {
        return {
          imgPath: it,
          url: it
        }
      }):[]
    }
  }
  visible.value = true;
  const {code, data} = await getAllClassify();
  if(code==='') classifyList.value = data;
}

// 动态图
const beforeAvatarUpload = async(rawFile, type) => {
  console.log(rawFile, type, 'before')
  if(rawFile.size / 1024 / 1024 > 5 && (dynamicData.value.fileType===1 || type==='cover')) {
    ElMessage.error('图片大小不能超过5M!')
    return false;
  }
  if(dynamicData.value.fileType===2&&type!=='cover') {
    return await new Promise(async (resolve, reject) => {
      let isMp4success = await getMp4Time(rawFile); // 视频时长
      if (isMp4success * 1 < 900) {
          resolve(true);
      } else {
          ElMessage.error('视频时长不能超过15分钟!')
          reject(false);
      }
    })
  }
  return true;
}
// 获取视频长度
function getMp4Time(file) {
  return new Promise(async (resolve, reject) => {
    let url = URL.createObjectURL(file);
    let audioElement = new Audio(url);
    let durtaion = 0;
    // 下面需要注意的是在监听loadedmetadata绑定的事件中对duration直接进行赋值是无效的，需要在fun回调函数中进行赋值
    audioElement.addEventListener("loadedmetadata", function () {
        //音频/视频的元数据已加载时，会发生 loadedmetadata 事件
        durtaion = audioElement.duration; //时长以秒作为单位
        fun(parseFloat(durtaion).toFixed(1))
    });
    let fun = (s) => {
        durtaion = s;
        resolve(durtaion)
    };
  })
}

// 上传图片
function handleImageSuccess (response, file, fileList, type) {
  const url = response.data.url;
  let field = ''
  if(type==='cover') {
    field = type
  } else {
    field = dynamicData.value.fileType===1?'fileUrl':'videoUrl';
  }
  dynamicData.value[field].push({
    imgPath: url,
    url: url,
    uid: file.uid
  })
  if(type==='cover') {
    coverRef.value.clearValidate();
  } else {
    dynamicData.value.fileType===1?imgRef.value.clearValidate():videoRef.value.clearValidate()
  }
}
function handleCoverSuccess(response, file, fileList) {
  handleImageSuccess(response, file, fileList, 'cover')
}

function handlePictureCardPreview (file) {
  detailImage.value = file.imgPath;
  imgVisible.image = true;
}
// 移除图片
function handleRemove (file, type) {
  const { uid } = file
  let field = ''
  if(type==='cover') {
    field = type
  } else {
    field = dynamicData.value.fileType===1?'fileUrl':'videoUrl';
  }
  const urlIndex = dynamicData.value[field].findIndex(x => x.uid === uid)
  if(urlIndex > -1) dynamicData.value[field].splice(urlIndex, 1)
}
// 移除封面
function handleCoverRemove(file) {
  handleRemove(file, 'cover')
}

//删除已选商品
function delProduct(item) {
  products.value.splice(item.$index, 1);
  dynamicData.value.productIds = products.value.map(it=>it.productId);
}
/* 选择商品 */
const addProduct = () => {
  isShowManualAdd.value = true
  selectShopList.value = [...products.value]
  getAll()
}
//获取所有商品
// 初始化查询所有数据
const getAll = async () => {
  const res = await getClassifyGetAll(formInline.value)
  shopTotal.value = res.data.total
  shopListData.value = res.data.list
  nextTick(() => {
    for (let i = 0; i < shopListData.value.length; i++) {
      if (dynamicData.value.productIds.includes(shopListData.value[i].productId)) {
        const row = shopListData.value[i];
        multipleTableRef.value.toggleRowSelection(row, true);
      }
    }
  })
}
// 重置商品搜索条件
function clearData() {
  formInline.value = {...defaultProductParam};
  getAll();
}
// 分页
const handlePageChange = (val, type) => {
  formInline.value[type] = val
  getAll()
}

const handleSelect = (e, row) => {
  const tempIds = selectShopList.value.map(it=>it.productId) || [];
  if (tempIds.includes(row.productId)) {
    // 删除
    selectShopList.value.splice(selectShopList.value.findIndex(item => item === row.productId), 1);
  } else {
    // 新增
    selectShopList.value.push(row)
  }
}
const handleSelectAll = (e) => {
  if (e.length > 0) {
    e.forEach(item => {
      const tempIds = selectShopList.value.map(it=>it.productId);
      if (!tempIds.includes(item.productId)) {
        selectShopList.value.push(item)
      }
    });
  } else {
    // 当前页全部删除
    shopListData.value.forEach((row) => {
      const index = selectShopList.value.findIndex(item => item.productId === row.productId);
      selectShopList.value.splice(index, 1);
    });
  }
}

// 保存手动选择商品
const saveIdList = () => {
  const shopList = []
  if(selectShopList.value.length>5) {
    ElMessage(
      {
        message: '最多关联5件商品哦',
        type: 'error',
      }
    )
    return;
  }
  selectShopList.value.forEach((i) => {
    shopList.push(i.productId)
  })
  dynamicData.value.productIds = shopList
  products.value = [...selectShopList.value]
  closeSelect();
}
// 取消手动选择商品
const closeSelect = () => {
  isShowManualAdd.value = false;
  selectShopList.value = [];
  multipleTableRef.value?.clearSelection();
  formInline.value = {...defaultProductParam};
  shopTotal.value = 1;
}

// 取消
function close() {
  visible.value = false;
  dynamicData.value = new DynamicData();
  products.value = [];
}
//发布
const publish = async(formEl) => {
  if (!formEl) return
  await formEl.validate(async(valid) => {
    if(valid) {
      const params = {...dynamicData.value};
      const field = dynamicData.value.fileType===1?'fileUrl':'videoUrl';
      const api = dynamicData.value.recommendId?contentEdit:contentAdd;
      params.fileUrl =  dynamicData.value[field].map(it => it.url).join(',');
      if(dynamicData.value.fileType===2) {
        params.cover =  dynamicData.value.cover[0].url;
      } else {
        delete params.cover;
      }
      delete params.videoUrl;
      const {code} = await api(params);
      if(code==='') {
        close();
        ElMessage({
          message: `${dynamicData.value.recommendId?"修改":"添加"}成功`,
          type: 'success',
        });
        emits('reload');
  }
    } else {
      return false;
    }
  })
}

defineExpose({
  open
})
</script>

<style lang="scss" scoped>
  .preview-img {
    width: 100% !important;
    height: auto;
  }
  .hide_box :deep(.el-upload--picture-card) {
    display: none;
  }
  :deep(.el-upload-list) {
    video {
      height: 100%;
      width: 100%;
    }
  }
</style>
